﻿#pragma once

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef uint8_t MacAddr[6];

typedef uint8_t Ipv4Addr[4];

typedef struct Addresses {
  MacAddr source_mac_addr;
  Ipv4Addr source_ip_addr;
  MacAddr des_mac_addr;
  Ipv4Addr des_ip_addr;
} Addresses;

typedef enum None_or_Addresses_Tag {
  Some_Addresses,
  None_Addresses,
} None_or_Addresses_Tag;

typedef struct None_or_Addresses {
  None_or_Addresses_Tag tag;
  union {
    struct {
      struct Addresses some;
    };
  };
} None_or_Addresses;

typedef enum None_or_String_Tag {
  Some_String,
  None_String,
} None_or_String_Tag;

typedef struct None_or_String {
  None_or_String_Tag tag;
  union {
    struct {
      char *some;
    };
  };
} None_or_String;


/**
 * 获取默认的地址信息。
 * 包括源 MAC 地址、源 IP 地址、目的 MAC 地址。
 * 
 * @return 默认的地址信息
 */
struct None_or_Addresses get_default_addrs(void);


/**
 * 这个 device name 用于在 pcap_findalldevs() 返回的设备列表中寻找一个可用的设备。
 * 
 * @return 可用的设备名称。
 */
struct None_or_String find_default_dev_name(void);


/**
 * @brief 发送一个 DNS 查询数据包。
 * 
 * 该函数会构造一个 DNS 查询数据包，并发送到指定的 DNS 服务器。
 *
 * @param pkt_id DNS 数据包的 ID，用于将发送和接收的数据包匹配起来
 * @param s_port 源 UDP 端口，可以随意指定 1000-65535 之间的端口。回复的数据包将以该端口为目的端口。
 * @param addrs 发包需要的地址信息
 * @param domain 需要查询的域名
 * @return 表示是否发送成功
 */
uint8_t send_dns_packet(uint16_t pkt_id,
                        uint16_t s_port,
                        const struct Addresses *addrs,
                        const char *domain);
